import Stats from "stats.js"
import { createCamera } from "../threeRender/base/camera"
import { createControl } from "../threeRender/base/control"
import { createScene } from "../threeRender/base/scene"
//import { createCube } from "../threeRender/base/cube"
import { createRenderer } from "../threeRender/base/renderer"
import { initComposer, outlineObj } from "../threeRender/base/composer"
import { createLightOilModel } from "../threeRender/base/light"
import { createGridHelper, createAxesHelper } from "../threeRender/base/gridHelper"
import { disposeTexture, createFlowingLineTexture1 } from "../threeRender/texture"
import { createDynamicEnv } from "../threeRender/oilm/dynamicEnv"
import isMobileDevice from "../threeRender/utils/deviceType"
import * as resize from "../threeRender/system/resize"
import { gui, debugObject } from '../threeRender/system/gui'
import TWEEN, { add } from 'three/examples/jsm/libs/tween.module.js';

import * as THREE from "three"

const vector3 = new THREE.Vector3()

const colorList = [
    //卡其色
    '0xb69860',
    //浅黄
    '0xedd3a1',
    //枯色
    '0xe0c38c',
    //榛色
    '0xbfa46f',
    //樺茶色
    '0x726250',
    //朽葉色
    '0x917347',
    //路考茶
    '0x8c7042',
    //国防色
    '0x7b6c3e',
    //利休茶
    '0xa59564',
    //空五倍子色
    '0x9d896c',
    //生壁色
    '0x94846a',
    //肥後煤竹
    '0x897858',
    //媚茶
    '0x716246',
    //黄唐色
    '0xb98c46',
    //桑染
    '0xb79b5b',
    //黄橡
    '0xb68d4c',
    //芝翫茶
    '0xad7e4e',
    //狐色
    '0xc38743',
    //黄土色
    '0xc39143',
    //香染
    '0xad7d4c',
    //枇杷茶
    '0xae7c4f'
]

class OilApp1{
    static instance

    static getInstance() {
        return OilApp1.instance
    }
    constructor(container){
        //类创建阶段 单例模式 还有结构 和 行为阶段的设计模式
        if (OilApp1.instance) {
            return OilApp1.instance
        }
        OilApp1.instance = this

        // stat
        let stats = new Stats();
        stats.showPanel(0); // 0: fps, 1: ms, 2: mb, 3+: custom
        //document.body.appendChild(stats.dom);
        //document.querySelector("#webgl-app2").appendChild(stats.dom);
        stats.dom.className = "stats"
        stats.dom.style.display = 'none'
        this.stats = stats

        this.isAllowComposer = true

        if (isMobileDevice()) {
            alert("当前设备可能不支持WebGL，建议使用PC端进行浏览。")
            this.isAllowComposer = false
        }

        // console.log(container)
        console.log("场景初始化")
        // 相机 camera
        this.camera = createCamera()
        // 控制器
        this.controls = createControl(this.camera, container)
        // 场景 scene
        this.scene = createScene()
        // 渲染器 renderer
        this.renderer = createRenderer(container)

        // 开启模型对象的局部剪裁平面功能 如果不设置为true，设置剪裁平面的模型不会被剪裁
        this.renderer.localClippingEnabled = true;

        // 后处理渲染器 composer
        this.composer = initComposer(this.renderer, this.scene, this.camera)

        this.composerEffect = outlineObj([],this.renderer, this.scene, this.camera)

        // 目标渲染
        this.renderTarget = new THREE.WebGLCubeRenderTarget(256)
        this.renderTarget.texture.type = THREE.HalfFloatType
        this.rtCubeCamera = new THREE.CubeCamera(1, 1000, this.renderTarget)
        this.rtCubeCamera.layers.set(1)
        this.scene.userData.rtCubeCameraLayer = 1
        this.scene.userData.dynamicMap = this.renderTarget.texture

        createLightOilModel(this.scene)
        createDynamicEnv(this.scene)
        createGridHelper(this.scene)
        createAxesHelper(this.scene)

        this.flowingLineTexture1 = createFlowingLineTexture1()
        // resize
        resize.resizeEventListener(this.camera, this.renderer)

        // 场景组成内容 object3D
        //this.scene.add(createCube())
        gui.close()

    }
    _runTask(task, callback){
        let start = new Date()
        let that = this
        requestAnimationFrame(()=>{
        if(Date.now() - start < 16.6){
          //that.task()
          task()
          callback()
        }else{
          that._runTask(task, callback)
        }
      })
      //requestIdleCallback((idle)=>{
      //   if(idle.timeRemaining()>0){
      //       task()
      //	   callback()
      //   }else{
      //       _runTask(task,callback)
      //   }
      //})
    }
    runTask(task){
      let that = this
      return new Promise((resolve)=>{
        that._runTask(task,resolve)
      })
    }
    render() {
        // 渲染场景
        console.log("渲染场景...")
        const clock = new THREE.Clock()// 创建THREE.Clock对象，用于计算上次调用经过的时间
        //clock.getDelta()方法获得两帧的时间间隔，返回时间单位：秒
        //let T = clock.getDelta();
        
        //console.log('两帧渲染时间间隔',T*1000+'毫秒');
        //console.log('查看每秒渲染频率',1/T);
        const delta = clock.getDelta() // 获取自上次调用的时间差
        let previousTime = 0
        this.tick = () => {
            this.stats.update()
            const elapsedTime = clock.getElapsedTime()
            const deltaTime = elapsedTime - previousTime
            previousTime = elapsedTime

            // // Update controls
            this.controls && this.controls.update(delta)

            this.camera && this.camera.position.lerp(vector3.set(0.05 * Math.sin(elapsedTime), 0, 0.01 * Math.cos(elapsedTime)).add(this.camera.position), 0.05)

            // console.log(this.camera.position,this.controls.target)

            // Update dynamic-env
            this.scene && this.scene.userData.dynamicEnv && this.scene.userData.dynamicEnv.children.forEach(item => {
                if (item.userData.update) {
                    item.userData.update(deltaTime, elapsedTime)
                }
            })
            if(this.scene){
                this.scene.background.b = 0.02 * Math.sin(elapsedTime) + 0.04
            }

            if(this.renderer && this.scene){
                // rtCubeCamera
                this.rtCubeCamera.update(this.renderer, this.scene)
            }

            // Render
            if (this.isAllowComposer) {
                this.composer && this.composer.render(delta)
                this.composerEffect && this.composerEffect.render(delta)
            } else {
                this.renderer && this.renderer.render(this.scene, this.camera)
            }
            
            if (TWEEN && TWEEN.update()) {
                let result = TWEEN.update(delta)
                //if (!result) cancelAnimationFrame(animateId)
            }
        
            if(this.flowingLineTexture1){
                // 管道流动,更新管道纹理的偏移量
                // 管道流动速度
                let tubeOilSpeed = 0.01
                this.flowingLineTexture1.offset.x -= tubeOilSpeed
            }

            // Call tick again on the next frame
            this.tickId = window.requestAnimationFrame(this.tick)
        }
        //递归调用 实现实时渲染
        //this.tick()
        this.runTask(this.tick)
    }
    clear() {
        console.log("清理内存")
        // location.reload()
        resize.clear()
        //document.querySelector("#webgl-app2").removeChild(this.stats.dom)
        cancelAnimationFrame(this.tickId)
        this.tick = null
        this.scene.traverse(child => {
            if (child instanceof THREE.Mesh) {
                child.geometry.dispose()
                child.material.dispose()
            }
        })
        this.scene = null
        this.camera = null
        this.renderer.dispose()
        this.controls.dispose()
        disposeTexture()
    }
}

export { OilApp1 }